---
import { spineModelConfig } from "@/config/pioConfig";
import MessageBox from "./PioMessageBox.astro";
import { url } from "@/utils/url-utils";
---

<!-- Spine Web Player CSS 将在 script 中动态加载 -->{
  spineModelConfig.enable && (
    <div
      id="spine-model-container"
      style={`
      position: fixed;
      ${spineModelConfig.position.corner.includes("right") ? "right" : "left"}: ${spineModelConfig.position.offsetX}px;
      ${spineModelConfig.position.corner.includes("top") ? "top" : "bottom"}: ${spineModelConfig.position.offsetY}px;
      width: ${spineModelConfig.size.width}px;
      height: ${spineModelConfig.size.height}px;
      pointer-events: auto;
      z-index: 1000;
    `}
    >
      <div id="spine-player-container" style="width: 100%; height: 100%;" />
      <div id="spine-error" style="display: none;" />
    </div>
  )
}

<!-- 引入消息框组件 -->
<MessageBox />

<script define:vars={{ spineModelConfig, modelPath: url(spineModelConfig.model.path), atlasPath: url(spineModelConfig.model.path.replace(".json", ".atlas")), cssPath: url("/pio/static/spine-player.min.css"), jsPath: url("/pio/static/spine-player.min.js") }}>
  // 动态加载 Spine CSS（带本地备用）
  function loadSpineCSS() {
    if (!spineModelConfig.enable) return;

    // 检查是否已经加载
    const existingLink = document.querySelector('link[href*="spine-player"]');
    if (existingLink) return;

    // 首先尝试加载 CDN CSS
    const cdnLink = document.createElement("link");
    cdnLink.rel = "stylesheet";
    cdnLink.href =
      "https://unpkg.com/@esotericsoftware/spine-player@4.2.*/dist/spine-player.min.css";

    // 监听加载失败事件，自动回退到本地文件
    cdnLink.onerror = function () {
      console.warn("⚠️ Spine CSS CDN failed, trying local fallback...");

      // 移除失败的 CDN link
      if (cdnLink.parentNode) {
        cdnLink.parentNode.removeChild(cdnLink);
      }

      // 创建本地备用 CSS link
      const localLink = document.createElement("link");
      localLink.rel = "stylesheet";
      localLink.href = cssPath;
      localLink.onerror = function () {
        console.error("❌ Failed to load Spine CSS");
      };

      document.head.appendChild(localLink);
    };

    document.head.appendChild(cdnLink);
  }

  // 消息框功能已移至公共组件 MessageBox.astro
  let isClickProcessing = false; // 防止重复点击的标志
  let lastClickTime = 0; // 记录最后一次点击时间

  // 全局变量，防止重复初始化
  window.spineModelInitialized = window.spineModelInitialized || false;
  window.spinePlayerInstance = window.spinePlayerInstance || null;

  // 消息显示函数 - 使用公共消息框组件
  function showMessage(message) {
    // 使用公共消息框组件
    if (window.showModelMessage) {
      window.showModelMessage(message, {
        containerId: "spine-model-container",
        displayTime: spineModelConfig.interactive.messageDisplayTime || 3000
      });
    }
  }

  // 更新响应式显示
  function updateResponsiveDisplay() {
    if (!spineModelConfig.enable) return;

    const container = document.getElementById("spine-model-container");
    if (!container) return;

    // 检查移动端显示设置
    if (
      spineModelConfig.responsive.hideOnMobile &&
      window.innerWidth <= spineModelConfig.responsive.mobileBreakpoint
    ) {
      container.style.display = "none";
    } else {
      container.style.display = "block";
    }
  }

  // 清理函数
  function cleanupSpineModel() {
    console.log("🧹 Cleaning up existing Spine model...");

    // 清理消息显示（使用公共组件）
    if (window.clearModelMessage) {
      window.clearModelMessage();
    }

    // 清理现有的播放器实例
    if (window.spinePlayerInstance) {
      try {
        if (window.spinePlayerInstance.dispose) {
          window.spinePlayerInstance.dispose();
        }
      } catch (e) {
        console.warn("Error disposing spine player:", e);
      }
      window.spinePlayerInstance = null;
    }

    // 清理容器内容
    const playerContainer = document.getElementById("spine-player-container");
    if (playerContainer) {
      playerContainer.innerHTML = "";
    }

    // 重置初始化标志
    window.spineModelInitialized = false;
  }

  async function initSpineModel() {
    if (!spineModelConfig.enable) return;

    // 检查移动端显示设置，如果隐藏则不加载运行时
    if (
      spineModelConfig.responsive.hideOnMobile &&
      window.innerWidth <= spineModelConfig.responsive.mobileBreakpoint
    ) {
      console.log("📱 Mobile device detected, skipping Spine model initialization");
      const container = document.getElementById("spine-model-container");
      if (container) container.style.display = "none";
      return;
    }

    // 检查是否已经初始化
    if (window.spineModelInitialized) {
      console.log("⏭️ Spine model already initialized, skipping...");
      return;
    }

    console.log("🎯 Initializing Spine Model...");

    // 先清理可能存在的旧实例
    cleanupSpineModel();

    // 首先加载 CSS
    loadSpineCSS();

    // 加载 Spine Web Player 运行时
    const loadSpineRuntime = () => {
      return new Promise((resolve, reject) => {
        if (typeof window.spine !== "undefined") {
          console.log("✅ Spine runtime already loaded");
          resolve();
          return;
        }

        console.log("📦 Loading Spine runtime...");
        const script = document.createElement("script");
        script.src =
          "https://unpkg.com/@esotericsoftware/spine-player@4.2.*/dist/iife/spine-player.min.js";
        script.onload = () => {
          console.log("✅ Spine runtime loaded from CDN");
          resolve();
        };
        script.onerror = (error) => {
          console.warn("⚠️ CDN failed, trying local fallback...");

          // 尝试本地回退
          const fallbackScript = document.createElement("script");
          fallbackScript.src = jsPath;
          fallbackScript.onload = () => {
            console.log("✅ Spine runtime loaded from local fallback");
            resolve();
          };
          fallbackScript.onerror = () => {
            reject(new Error("Failed to load Spine runtime"));
          };
          document.head.appendChild(fallbackScript);
        };
        document.head.appendChild(script);
      });
    };

    // 等待 Spine 库加载
    const waitForSpine = () => {
      return new Promise((resolve, reject) => {
        let attempts = 0;
        const maxAttempts = 50;

        const check = () => {
          attempts++;
          if (typeof window.spine !== "undefined" && window.spine.SpinePlayer) {
            console.log("✅ Spine runtime loaded");
            resolve();
          } else if (attempts >= maxAttempts) {
            reject(new Error("Spine runtime loading timeout"));
          } else {
            setTimeout(check, 100);
          }
        };
        check();
      });
    };

    try {
      // 首先加载 Spine 运行时
      await loadSpineRuntime();

      // 然后等待 Spine 对象可用
      await waitForSpine();

      // 标记为已初始化
      window.spineModelInitialized = true;

      // 创建 SpinePlayer
      const player = new window.spine.SpinePlayer("spine-player-container", {
        skeleton: modelPath,
        atlas: atlasPath,
        animation: "idle",
        backgroundColor: "#00000000", // 透明背景
        showControls: false, // 隐藏控件
        alpha: true,
        premultipliedAlpha: false,
        success: (player) => {
          console.log("🎉 Spine model loaded successfully!");

          // 保存播放器实例引用
          window.spinePlayerInstance = player;

          // 初始化完成后设置默认姿态
          setTimeout(() => {
            if (player.skeleton) {
              try {
                player.skeleton.updateWorldTransform();
                player.skeleton.setToSetupPose();
              } catch (e) {
                console.warn("Error positioning skeleton:", e);
              }
            }
          }, 500);

          // 设置交互功能
          if (spineModelConfig.interactive.enabled) {
            const canvas = document.querySelector(
              "#spine-player-container canvas"
            );
            if (canvas) {
              canvas.addEventListener("click", () => {
                // 防抖处理：防止重复点击
                const currentTime = Date.now();
                if (isClickProcessing || currentTime - lastClickTime < 500) {
                  return; // 500ms 内重复点击忽略
                }

                isClickProcessing = true;
                lastClickTime = currentTime;

                // 随机播放点击动画
                const clickAnims =
                  spineModelConfig.interactive.clickAnimations ||
                  (spineModelConfig.interactive.clickAnimation
                    ? [spineModelConfig.interactive.clickAnimation]
                    : []);

                if (clickAnims.length > 0) {
                  try {
                    const randomClickAnim =
                      clickAnims[Math.floor(Math.random() * clickAnims.length)];
                    player.setAnimation(randomClickAnim, false);

                    // 动画播放完成后回到待机状态
                    setTimeout(() => {
                      const idleAnims =
                        spineModelConfig.interactive.idleAnimations;
                      const randomIdle =
                        idleAnims[Math.floor(Math.random() * idleAnims.length)];
                      player.setAnimation(randomIdle, true);
                    }, 2000);
                  } catch (e) {
                    console.warn("Failed to play click animation:", e);
                  }
                }

                // 显示随机消息
                const messages = spineModelConfig.interactive.clickMessages;
                if (messages && messages.length > 0) {
                  const randomMessage =
                    messages[Math.floor(Math.random() * messages.length)];
                  showMessage(randomMessage);
                }

                // 500ms 后重置防抖标志
                setTimeout(() => {
                  isClickProcessing = false;
                }, 500);
              });

              // 设置待机动画循环
              if (spineModelConfig.interactive.idleAnimations.length > 1) {
                setInterval(() => {
                  try {
                    const idleAnims =
                      spineModelConfig.interactive.idleAnimations;
                    const randomIdle =
                      idleAnims[Math.floor(Math.random() * idleAnims.length)];
                    player.setAnimation(randomIdle, true);
                  } catch (e) {
                    console.warn("Failed to play idle animation:", e);
                  }
                }, spineModelConfig.interactive.idleInterval);
              }
            }
          }

          // 添加拖拽功能
          const container = document.getElementById("spine-model-container");
          if (container) {
            let isDragging = false;
            let dragStart = { x: 0, y: 0 };
            let containerStart = { x: 0, y: 0 };

            // 鼠标事件
            container.addEventListener("mousedown", (e) => {
              if (e.button !== 0) return; // 只响应左键
              isDragging = true;
              dragStart = { x: e.clientX, y: e.clientY };

              const rect = container.getBoundingClientRect();
              containerStart = { x: rect.left, y: rect.top };

              container.style.cursor = "grabbing";
              e.preventDefault();
            });

            document.addEventListener("mousemove", (e) => {
              if (!isDragging) return;

              const deltaX = e.clientX - dragStart.x;
              const deltaY = e.clientY - dragStart.y;

              const newX = containerStart.x + deltaX;
              const newY = containerStart.y + deltaY;

              // 边界检查
              const maxX = window.innerWidth - container.offsetWidth;
              const maxY = window.innerHeight - container.offsetHeight;

              const clampedX = Math.max(0, Math.min(newX, maxX));
              const clampedY = Math.max(0, Math.min(newY, maxY));

              container.style.left = clampedX + "px";
              container.style.right = "auto";
              container.style.top = clampedY + "px";
              container.style.bottom = "auto";
            });

            document.addEventListener("mouseup", () => {
              if (isDragging) {
                isDragging = false;
                container.style.cursor = "grab";
              }
            });

            // 触摸事件（移动端支持）
            container.addEventListener("touchstart", (e) => {
              if (e.touches.length !== 1) return;
              isDragging = true;
              const touch = e.touches[0];
              dragStart = { x: touch.clientX, y: touch.clientY };

              const rect = container.getBoundingClientRect();
              containerStart = { x: rect.left, y: rect.top };

              e.preventDefault();
            });

            document.addEventListener("touchmove", (e) => {
              if (!isDragging || e.touches.length !== 1) return;

              const touch = e.touches[0];
              const deltaX = touch.clientX - dragStart.x;
              const deltaY = touch.clientY - dragStart.y;

              const newX = containerStart.x + deltaX;
              const newY = containerStart.y + deltaY;

              // 边界检查
              const maxX = window.innerWidth - container.offsetWidth;
              const maxY = window.innerHeight - container.offsetHeight;

              const clampedX = Math.max(0, Math.min(newX, maxX));
              const clampedY = Math.max(0, Math.min(newY, maxY));

              container.style.left = clampedX + "px";
              container.style.right = "auto";
              container.style.top = clampedY + "px";
              container.style.bottom = "auto";

              e.preventDefault();
            });

            document.addEventListener("touchend", () => {
              isDragging = false;
            });

            // 设置初始光标样式
            container.style.cursor = "grab";

            // 窗口大小变化时重新检查边界
            window.addEventListener("resize", () => {
              const rect = container.getBoundingClientRect();
              const maxX = window.innerWidth - container.offsetWidth;
              const maxY = window.innerHeight - container.offsetHeight;

              if (rect.left > maxX) {
                container.style.left = maxX + "px";
                container.style.right = "auto";
              }
              if (rect.top > maxY) {
                container.style.top = maxY + "px";
                container.style.bottom = "auto";
              }
            });
          }

          console.log("✅ Spine model setup complete!");
        },
        error: (player, reason) => {
          console.error("❌ Spine model loading error:", reason);

          const errorDiv = document.getElementById("spine-error");
          if (errorDiv) {
            errorDiv.style.display = "block";
            errorDiv.innerHTML = `
              <div style="color: #ff4444; padding: 20px; text-align: center; font-size: 14px;">
                <div>⚠️ Spine 模型加载失败</div>
                <div style="font-size: 12px; margin-top: 8px; color: #888;">${reason}</div>
              </div>
            `;
          }

          const canvas = document.getElementById("spine-canvas");
          if (canvas) canvas.style.display = "none";
        },
      });
    } catch (error) {
      console.error("Spine model initialization error:", error);

      // 重置初始化标志，允许重试
      window.spineModelInitialized = false;

      const errorDiv = document.getElementById("spine-error");
      if (errorDiv) {
        errorDiv.style.display = "block";
        errorDiv.innerHTML = `
          <div style="color: #ff4444; padding: 20px; text-align: center; font-size: 14px;">
            <div>⚠️ Spine 运行时加载失败</div>
            <div style="font-size: 12px; margin-top: 8px; color: #888;">${error instanceof Error ? error.message : "未知错误"}</div>
          </div>
        `;
      }
    }
  }

  // 监听页面卸载事件，清理资源
  window.addEventListener("beforeunload", cleanupSpineModel);

  // 监听 Swup 页面切换事件（如果使用了 Swup）
  if (typeof window.swup !== "undefined" && window.swup.hooks) {
    window.swup.hooks.on("content:replace", () => {
      // 只更新响应式显示，不重新创建模型
      setTimeout(() => {
        updateResponsiveDisplay();
      }, 100);
    });
  }

  // 监听 popstate 事件（浏览器前进后退）
  window.addEventListener("popstate", () => {
    setTimeout(() => {
      updateResponsiveDisplay();
    }, 100);
  });

  // 监听窗口大小变化
  window.addEventListener("resize", updateResponsiveDisplay);

  // 页面加载完成后初始化（只初始化一次）
  if (document.readyState === "loading") {
    document.addEventListener("DOMContentLoaded", initSpineModel);
  } else {
    initSpineModel();
  }
</script>
